
Issues:

-- Define the labels in the finite elements that to be a vector no matter what.
labels = fes.label; # individual element labels
if length(fes.label) == 0
    labels = zeros(FInt, nfes);
end
Implemented  05/07/2017

-- Get rid of the property modules: replace with definition in the materials.
Needs careful deliberation.
Initiated 05/22/2017. Implementation started 05/24/2017.

-- In algorithms, assume that  the finite element model machine  is submitted as
input instead of the material parameters and the finite elements. Similarly to
SPyFE.
Initiated 05/02/2017. It is working in  heat diffusion 05//23/2017.

-- There are some loops  in the finite element model machines which
are not instrumented with @inbounds end @fastmath.

-- Implement coordinate system module. Replace MaterialOrientationModule
with it.
Implemented 05/05/2017.

-- How to work with anisotropic materials?  Strains in local coordinate system,
ddisplacements in the global coordinate system?  Or both in the global
coordinate system, and a transformation for the material property matrix?

-- The  base FEMM should create a coordinate system  that
allows for  pre-computation: identity matrix.

-- Special FEMM  heat transfer  on the surface.
And special FEMM for  the boundary condition on the surface?
We already have one for  the Winkler  boundary condition?
Implemented 05/22/2017..

-- The Poisson  heat conduction problem:
Conductivity
  6.043066 seconds (2.00 M allocations: 1.296 GB, 13.11% gc time)
Why are there 2 million allocations  (this is the number of triangles)?
Profiling? Could be array slicing?
Solution: It was the type instability due to the keyword arguments  used  for
the finite element sets. Keyword arguments  should be removed everywhere.

-- What is __precompile__() for?

-- What is @propagate_inbounds for?

-- julia> A = rand(3,4);

julia> B = A .- mean(A,1)
3×4 Array{Float64,2}:
  0.343976   0.427378  -0.503356  -0.00448691
 -0.210096  -0.531489   0.168928  -0.128212
 -0.13388    0.104111   0.334428   0.132699

julia> mean(B,1)
1×4 Array{Float64,2}:
 0.0  0.0  0.0  0.0

 -- Use return type annotations.

 -- Replace explicit loops with in-place matrix mult functions? A_mult_B! and so on...
 Notes: Tested for  the heat conduction model. Around 20% slower: more
 memory allocations.
 A_mul_Bt!(kappa_bargradNT, (Jac*w[j])*kappa_bar, gradN); # intermediate result
 A_mul_B!(Ke1, gradN, kappa_bargradNT);
 Ke[:,:] += Ke1[:,:]
 Conductivity
  8.454714 seconds (10.00 M allocations: 2.398 GB, 10.42% gc time)
versus
A_mul_Bt!(kappa_bargradNT, (Jac*w[j])*kappa_bar, gradN); # intermediate result
A_mul_B!(Ke1, gradN, kappa_bargradNT);
@inbounds for nx = 1:Kedim # complete the lower triangle
  @inbounds for mx = 1:Kedim
    Ke[mx, nx] = Ke[mx, nx] + Ke1[nx, mx]
  end
end
Conductivity
  9.182616 seconds (4.00 M allocations: 1.504 GB, 10.83% gc time)
versus
All-loops
Conductivity
    6.209980 seconds (2.05 M allocations: 1.298 GB, 12.54% gc time)

-- add_nhnt!(): test and include  in the code
Implemented.

-- WARNING: both MeshTriangleModule and MeshQuadrilateralModule export "Q4toT3";
Conflict resolved.

-- For symmetric elementwise matrices compute only the upper triangle in the
integration point loop; complete the matrix only below the loop.
Alternatively don't bother completing the lower triangle if the assembler
works only on the upper triangle.
Implemented 05/1/17: compute only upper triangle in the integration group,
complete the full matrix underneath the loop. Not completing the triangle
would not work if the assembler expected the full matrix.

-- Test the speed  with the material orientation  matrix Different from identity.

--
C:\Users\PetrKrysl\AppData\Local\Julia-0.6.0\bin\julia.exe
C:\Users\PetrKrysl\AppData\Local\Julia-0.7.0-DEV\bin\julia.exe

--
Other workarounds include "types as tags" (search; NumericFuns.jl is one example
among many), FastAnonymous.jl, and in julia 0.4 the new call() overloading.

-- Move the code for axial symmetry and other dimension
into the FEMM modules: type  parameter?

-- SymPy.jl or SymEngine.jl.

-- I think Julia is about giving you the tools to build these things.
If you want "the tool for auto-optimizing scientific computing code",
that would ParallelAccelerator.jl

-- Jacobian functions for zero-dimensional manifolds.
Implemented 05/20/2017

-- export setRm!
export getRm!  Not used?
Implemented 05/20/2017

--
@code_warntype Jacobiansurface(FEMMBase, FFltMat, FFltMat, FIntMat, FFltMat)

-- replace error() with assert in FEMMBaseModule
Implemented 05/01/2017

-- return fens,nfes            # I think I should not be overwriting the input!
What is that about?

-- FEMMBaseModule:  redesign  integration methods  by parameterising with
the function type.
Implementation completed.

-- VTK export: export  cell data.
Implemented  July 2017.

-- Implement  element  fields. (Analogy to  nodal fields.)
Implemented partially: so far only elementwise constant field has been
implemented (or rather used  in code)..

-- To get type stability  (to eliminate that pesky allocation during
calls in a loop), one has to  define:
    femmbase::FEMMBase{S, F} # base finite element modeling machine
Implemented

-- Type function cross(theta, v) and others in the rotation module.
It would seem that  cross() is no longer needed in the rotation module.
Implemented

-- NodalField constructors!  No keywords.
Implemented 05/17/2017

-- ; context...
Replace with  positional arguments.

--  thermalstress{MR<:DeformationModelReduction3D}(::Type{MR},
                        self::MaterialDeformationLinear, dT= 0.0)
    and also update!() should probably use buffer passed in and filled.
    In order to avoid allocations...
Implemented  05/22/2017: removed thermal stress. Stress and strain vectors are
now passed in as buffers.

-- stochastic lifestyle website

-- update!() for the material could have  another method  with deformation
gradient going in instead of strain.

--- Right now the tangent moduli are computed  just once  for the
small-deformation elastic model.
self.material.tangentmoduli!(self.material, D, 0.0, 0.0, loc, 0)
That is fine when the material is homogeneous within  the  domain,
but it needs to be made more general for heterogeneous structures.

-- Conversion between  matrices and vectors:  must decide which is which
and stick to it.
const a = reshape(collect(1:1000),1000,1);
@time vec(a);
@time squeeze(a,2);

-- Acoustic ABC: surface FEMM?
Implemented 05/30/2017

-- otherdimensionunity(loc::FFltMat, conn::CC, N::FFltMat)::FFlt where {CC}
and elsewhere: CC a union of  vector and column or row matrix?

-- gatherdofnums!(self::Field, dest::A, conn::FIntVec) where {A}
or
gatherdofnums!(self::Field, dest::A, conn::CC) where {A, CC}
Perhaps CC<:AbstractArray
Implemented August 2017

-- Packages:  symbol-gen, compare-files

--- function inspectintegpoints(self::FEMMDeforLinear,
              geom::NodalField{FFlt},  u::NodalField{T},
              dT::NodalField{FFlt},
              felist::FIntVec,
              inspector::Function,  idat; context...) where {T<:Number}
change to
function inspectintegpoints(self::FEMMDeforLinear,
              geom::NodalField{FFlt},  u::NodalField{T},
              dT::NodalField{FFlt},
              felist::FIntVec,
              inspector::F,  idat::D; context...) where {T<:Number, F<:Function, D}


-- Can I do this for all finite elements in one shot?
for i = 1:count(fb.fes)
  getconn!(fb.fes, conn, i);
  gathervalues_asmat!(geom, x, conn);# retrieve element coordinates
  idat = inspectintegpoints(self,  geom,  u,  dT,
            [i],  idi_inspector,  idat; output = output,  context...);
end
Implemented 06/03/2017: the inspector function now does not need to refer to
data defined within a loop  over the finite elements, and the inspector can be
called just once for all the finite elements.

-- inspectintegpoints:  the inspector function has been redefined.  The
arguments are different.  The description needs to be updated and all references
need to be updated. Implemented: July 2017.

--- Methods that  fill a buffer should also  return the buffer as a convenience.
Apparently, that is the Julia convention.
Implemented  06 17 2017

-- Instead of
function test_vectorized(a, a_old)
    @. a[:] = a_old[:] * 2
end
use
@views function test_vectorized3(a, a_old)
    @. a[:] = a_old[:] * 2
end

-- Instead of "restart" use  https://github.com/timholy/Revise.jl

-- Should algorithms print out anything (for instance warnings)?
Option: return an error status as part of the model data.

-- Use static arrays (stack-allocated) in the material update methods.

-- rotatestiffness!   Should probably be redesigned for efficiency
On hold.  07/22/2017

-- Atom packages
Julia-client
language-Julia
minimap
auto-indent
split-diff
simple-drag-drop-text

-- Atom themes:
"behave" is an excellent dark theme:  very easy on the eyes

-- Pkg.clone("https://github.com/JuliaDiffEq/DiffEqTutorials.jl")
using IJulia
notebook(dir=Pkg.dir("DiffEqTutorials"))
using IJulia; notebook(detached=true, dir="C:\\Users\\PetrKrysl\\.julia\\v0.6\\FinEtools")


-- When  Atom would not start: run this
  atom --clear-window-state
  in a command window

-- Start notebook:
function examples()
  path = joinpath(@__DIR__,"..","examples")
  @eval using IJulia
  @eval notebook(dir=$path)
end

-- Mean-strain extrapolation technology: need to consider the thermal properties
of the stabilization material. It needs to produce  thermal strains  just as
the real material.

-- Search for JFinEALE: some examples have not been converted  yet.

-- For the QR factorization use qrfact!(A, pivot=Val(false))

-- Return additional data from Abaqus  reader  as a dictionary.
Implemented: 09/09/2017

-- This is a bit of a puzzle: How to transform (rotate) stresses for
  lower-dimensional  finite elements embedded in higher dimensional spaces?
  The transformation matrix is rectangular, not square.

-- in  keymap.cson
'atom-text-editor':
  'ctrl-space': 'autocomplete-plus:activate'

'.platform-win32 .find-and-replace, .platform-linux .find-and-replace':
  'alt-shift-ctrl-r': 'find-and-replace:replace-next'

-- Mesh import: return dictionary of output data
Implemented: 09/09/2017

-- Running Julia in  the git bash terminal (mintty) is an excellent alternative:
the shell mode works.

-- VS code:
Extensions:
Bookmarks, Julia Language Support 0.8, Partial Diff

Setup of the executable:
{
    "julia.executablePath": "C:\\Users\\PetrKrysl\\AppData\\Local\\Julia-0.7.0-DEV\\bin\\julia.exe",
}

Key bindings:
// Place your key bindings in this file to overwrite the defaults
[
{ "key": "ctrl+1", "command": "extension.partialDiff.markSection1",
        "when": "editorTextFocus" },
{ "key": "ctrl+2", "command": "extension.partialDiff.markSection2AndTakeDiff",
        "when": "editorTextFocus" },
{ "key": "ctrl+3", "command": "extension.partialDiff.diffSelectionWithClipboard",
        "when": "editorTextFocus" },
{ "key": "ctrl+shift+i", "command": "editor.action.reindentlines",
        "when": "editorTextFocus" },
]

User settings:
{
    "julia.executablePath": "C:\\Users\\PetrKrysl\\AppData\\Local\\Julia-0.6.0\\bin\\julia.exe",
    "terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe",
    "workbench.colorTheme": "Tomorrow Night Blue",
    "julia.runlinter": false,
    "window.zoomLevel": 0,
    // When opening a file, `editor.tabSize` and `editor.insertSpaces` will be detected based on the file contents.
    "editor.detectIndentation": true,
    // Controls if the editor should automatically adjust the indentation when users type, paste or move lines. Indentation rules of the language must be available.
    "editor.autoIndent": true,
    "editor.wordWrap": "on",
    "editor.wrappingIndent": "indent",
}

-- Speed up the elementwise-field transfer the same way it's been done for the nodal fields.
(Using a search structure based on partitioning and sub- meshes.)

-- Atom platformio terminal:  set Auto run command to
/c/Users/PetrKrysl/AppData/Local/Julia-0.7.0-DEV/bin/julia.exe
set Show override to
C:\Program Files\Git\bin\bash.exe

-- Key bindings for Atom

'atom-text-editor':
  'ctrl-space': 'autocomplete-plus:activate'

'.platform-win32 .find-and-replace, .platform-linux .find-and-replace':
  'alt-shift-ctrl-r': 'find-and-replace:replace-next'

'.platform-linux atom-workspace, .platform-win32 atom-workspace':
  'alt-ctrl-shift-enter': 'platformio-ide-terminal:insert-selected-text'

-- Failures to indent code properly in Atom and VS code for lines with
continuation are not specific to  Julia.
Both fail for instance for  C-language code.

-- Configuring PyPlot to use Anaconda
ENV["PYTHON"]="C:\\ProgramData\\Anaconda3\\python.exe"
ENV["PYTHON"]="C:\\Users\\PetrKrysl\\Documents\\WinPython-64bit-3.6.3.0Qt5\\python-3.6.3.amd64\\python.exe"
Pkg.build("PyCall")

-- VS code: To insert a symbol, simply execute the Unicode: Insert Math Symbol command and type in the name of your desired symbol or select it from the drop-down list. (Unicode Latex extension..)

-- SIMD optimizations are not turned on by default, because they only speed up very particular kinds of code, and turning them on everywhere would slow down the compiler too much.

function mysum3(A)
    s = zero(eltype(A))
    @simd for a in A
        s += a
    end
    return s
end

-- Implement
fen2fe  = FENodeToFEMap(fes, nnodes(geom))
or in other words use the tuple-based connectivity. Status: implemented in November 2017.

-- Do not export ANYTHING? Then  one knows where methods come from because
they need to be explicitly brought in. Implemented: no source files export
functions, only the top-level module exports the public interface.

-- Instead of a geometry field, pass the finite element nodes? Then the node
data could be stored as immutable, with possible performance gains.

-- Have  multiple concrete types for fields? Some mutable, some immutable?

-- When fusing nodes, how about finding the intersection of the bounding
boxes, then finding which nodes fall into those boxes, and then only
checking for proximity for those nodes? Implemented: search speeded up by
    a factor of around 3.

-- Why are there so many allocations in fusenodes()?

-- Number all degrees of freedom (instead of just the free ones). This will 
then allow the assembler to assemble the entire matrix, not just 
the free-free block. How to supply the number of degrees of freedom to the 
assembler when it is getting constructed? Actually, all methods allow
for the assembler to be constructed outside of the method. In that case,
we can construct that assembler not just from the number of free degrees 
of freedom, but from the total number of  degrees of freedom.

-- Naming of formal parameters that are modified inside a function:
module mmmmmmmmmmmm
function f2!(a!) 
  a![1] = 2; 
end
end 
B=[5]
using .mmmmmmmmmmmm: f2!
f2!(B)
println("B = $(B)")
I like that a! is telling me inside the function that I’m changing something passed in as argument.

-- https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions
// Controls the font size in pixels.
    "editor.fontSize": 14,
    // Controls the font family.
    "editor.fontFamily": "Fira Code",
    "editor.fontLigatures": true
    